//
//  ViewController.m
//  MVP_DesignModel_OCVersion
//
//  Created by DeLongYang on 2017/7/19.
//  Copyright © 2017年 DeLongYang. All rights reserved.
/*
    2017-7-20 
    这是 一个 MVP 设计的演示
    1.0 整个页面类似于H5里面中行元素布局只是 每行就是一个 cell
        每个header 也是一行 每个margin 也是一行 
    2017-7-21 更新
     1.0 笔者认为 讲到单元测试 如果 MVP的 一个特点是可以 方便单元测试
    也就是数据可以是分段的 我们一次加载一部分的数据 以达到单元测试的目的 测试一下 
     而不用影响其他的 在开发的过程中也是如此 一点点的加载数据
     2.0 笔者认为返回的数据 是我们设计Model 数据层次的关键 和 刷新cell 的依据
    3.0  实验发现如果没有设置 appTransport 选项 即使加载 http 的图片也无法加载出来
 
 
 */

#import "ViewController.h"
#import "ActionHandler.h"
#import "TemplateChannelModel.h"
#import "TemplateContainerMode.h"
#import "TemplateCellProtocol.h"
#import "TemplateSorbRenderProtocol.h"   //  header

@interface ViewController ()<ActionHandlerDelegate,UITableViewDelegate,UITableViewDataSource>

@property (weak, nonatomic) IBOutlet UITableView *tableView;

@property (strong,nonatomic) ActionHandler *actionHanlder;

@property (strong,nonatomic) TemplateChannelModel *floorModel;


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.title = @"MVP DEMO";
    
    //  设置注册相应的 cell
    self.view.backgroundColor = [UIColor whiteColor];
    [self.tableView registTableViewCell];
    self.tableView.separatorStyle = UITableViewCellAccessoryNone;
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    
    //
    [self loadData];
    
}


/**
 加载 本地的数据
 */
- (void)loadData
{
    NSString* configFilePath = [[NSBundle mainBundle] pathForResource:@"food" ofType:@"json"];
    NSData* data = [NSData dataWithContentsOfFile:configFilePath];
    if (data == nil)
    {
        return;
    }
    
    NSError* error = nil;
    NSDictionary *dic = [[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error] mutableCopy];
    self.floorModel = [TemplateChannelModel mj_objectWithKeyValues:dic];
    
    //
    [self.tableView reloadData];
}


#pragma  mark ---- Setter Getter

- (ActionHandler *)actionHanlder{
    
    if (!_actionHanlder) {
        _actionHanlder = [[ActionHandler alloc]init];
    }
    return _actionHanlder;
}

#pragma  mark --- UITableView DataSoure
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return self.floorModel.floors.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // 不需要显示的 将代理方法显示出来
    TemplateContainerMode *containerMode = self.floorModel.floors[section];
    return [containerMode numberOfChildModelsInContainer];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    id<TemplateRenderProtocol> model = [self.floorModel rowModelAtIndexPath:indexPath];
    UITableViewCell<TemplateCellProtocol> *cell = [tableView dequeueReusableCellWithIdentifier:model.floorIdentifier];
    [cell processData:model];
    NSLog(@"cell identifie is %@",model.floorIdentifier);
    [cell tapOneBlock:^(NSIndexPath *indexPath) {
        __weak typeof (self) weakSelf = self;
        if ([model conformsToProtocol:@protocol(TemplateActionProtocol)]) {
            TemplateAction *action = [(id<TemplateActionProtocol>)model actionAtIndexPath:indexPath];
            [weakSelf.actionHanlder handleAction:action];
        }
    }];
    if (!cell) {
        return [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
    }
    return cell;
}

// 注意执行 TemplateCellProtocol 的 都是cell 类型
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    id<TemplateRenderProtocol> floor = [self.floorModel rowModelAtIndexPath:indexPath];
    if ([floor respondsToSelector:@selector(floorIdentifier)]) {
        NSString *identifier = [floor floorIdentifier];
        //  我们拿到了 是个 类方法 因为 cell 的高度 由cell 的类型和 mode 共同决定
        Class<TemplateCellProtocol>viewClass = NSClassFromString(identifier);
        CGSize size = [viewClass  calculateWithData:floor constraindeToSize:CGSizeMake(self.tableView.frame.size.width, 0)];
        return  size.height;
    }
    return 0;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    id <TemplateSorbRenderProtocol,TemplateRenderProtocol> floor = self.floorModel.floors[section];
    if ([floor conformsToProtocol:@protocol(TemplateSorbRenderProtocol)]) {
        NSString *headerIdentifier = [floor headerFloorIdentifier];
        if (headerIdentifier) {
            Class<TemplateCellProtocol> viewClass = NSClassFromString(headerIdentifier);
            CGSize size = [viewClass  calculateWithData:floor constraindeToSize:CGSizeMake(self.tableView.frame.size.width, 0)];
            return size.height;
        }
    }
    
    return 0;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    id <TemplateSorbRenderProtocol,TemplateRenderProtocol> floor = self.floorModel.floors[section];
    if ([floor conformsToProtocol:@protocol(TemplateSorbRenderProtocol)]) {
        id<TemplateSorbRenderProtocol> headerModel = [floor headerFloorModeAtIndex:section];
        if (headerModel) {
            NSString *identifier = [headerModel headerFloorIdentifier];
            UIView <TemplateCellProtocol> *headerView = (UIView <TemplateCellProtocol> *)[tableView dequeueReusableHeaderFooterViewWithIdentifier:identifier];
            [headerView processData:floor];
            return headerView;
        }
    }
    return nil;
}




#pragma  mark ---- 设置 cell 中subView 的tap 点击事件



/*
   注意这里并没有使用 UITableView的 select 代理因为 每个cell 中不同的区域的点击事件是不同的
    把这些事件封装在 cell 中的tapBlock 中
 */
#pragma mark ---- UITableView Delegate
// 此处设置 tableView 的点击事件
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    
}

#pragma mark ----  ActionHanlder Delegate

// 完成事件处理
- (void)actionHandler:(ActionHandler *)handler didHanlderAction:(TemplateAction *)action
{
    NSLog(@"handler did  handle action ");
}

// 将要开始事件处理
- (void)actionHandler:(ActionHandler *)handler willHandleAction:(TemplateAction *)action
{
    NSLog(@"handle will start to handle action");
}







@end
